package term

import (
	"context"
	"strconv"

	"mall/common/globalkey"
	"mall/common/modelx"
	"mall/common/utils/pointy"
	"mall/service/backend/common/errorx"
	"mall/service/backend/common/i18n"
	"mall/service/forum/model"
	"mall/service/forum/rpc/internal/svc"
	"mall/service/forum/rpc/internal/utils"
	"mall/service/forum/rpc/internal/utils/errorhandler"
	"mall/service/forum/rpc/types/forum"

	"github.com/zeromicro/go-zero/core/logx"
)

type BackendGetTermByIdLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewBackendGetTermByIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BackendGetTermByIdLogic {
	return &BackendGetTermByIdLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *BackendGetTermByIdLogic) BackendGetTermById(in *forum.TermIdReq) (*forum.TermInfo, error) {
	if in.Id == 0 {
		return nil, errorx.NewInvalidArgumentError(i18n.ValidationError)
	}

	res, err := l.svcCtx.ForumTerm.FindOne(l.ctx, in.Id)
	if err != nil {
		return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
	}

	var meta []*forum.MetaInfo
	if in.WithMeta != nil && *in.WithMeta > 0 {
		filterMap := make(map[string]map[string][]any)
		filterMap[model.ForumTermMetumColumns.TermID] = map[string][]any{
			"equalTo": []any{in.Id},
		}
		list, _, err := l.svcCtx.ForumTerm.GetMeta(l.ctx, model.M{}, -1, filterMap)
		if err != nil {
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}

		if len(list) > 0 {
			for _, v := range list {
				if v.MetaKey == "_thumbnail_id" || v.MetaKey == "_thumbnail_url" {
					continue
				}

				if len(v.MetaKey) > 0 && v.MetaValue.Valid {
					meta = append(meta, &forum.MetaInfo{
						Id:    &v.MetaID,
						Key:   &v.MetaKey,
						Value: &v.MetaValue.String,
					})
				}
			}
		}
	}

	var media []*forum.MediaInfo
	if in.WithMedia != nil && *in.WithMedia > 0 {
		filterMap := make(map[string]map[string][]any)
		filterMap[model.ForumAttachmentRelationshipColumns.ObjectID] = map[string][]any{
			"equalTo": []any{in.Id},
		}
		filterMap[model.ForumAttachmentRelationshipColumns.ObjectType] = map[string][]any{
			"equalTo": []any{globalkey.ForumAttachmentTypeTag},
		}
		var orderBy string = model.ForumAttachmentRelationshipColumns.AttachmentThumbnail + " DESC, " +
			model.ForumAttachmentRelationshipColumns.AttachmentOrder
		list, _, err := l.svcCtx.ForumTerm.GetMedia(l.ctx, model.M{
			"orderBy": orderBy,
		}, -1, filterMap)
		if err != nil {
			return nil, errorhandler.DefaultRepositoryError(l.Logger, err, in)
		}

		if len(list) > 0 {
			for _, v := range list {
				media = append(media, &forum.MediaInfo{
					Uid:       &v.AttachmentRelationshipID,
					Id:        pointy.GetPointer(strconv.FormatInt(int64(v.AttachmentID), 10)),
					Thumbnail: pointy.GetPointer(uint32(v.AttachmentThumbnail)),
					Order:     pointy.GetPointer(uint32(v.AttachmentOrder)),
					Uri:       &v.AttachmentSource,
					Url:       &v.AttachmentImageURL,
					AltText:   &v.AttachmentImageAlt,
					MetaData:  &v.AttachmentImageMeta,
				})
			}
		}
	}

	return &forum.TermInfo{
		Id:           &res.TermID,
		Name:         &res.Name,
		Slug:         &res.Slug,
		Taxonomy:     pointy.GetPointer(utils.FormatTaxonomy(int32(res.Taxonomy))),
		ParentId:     &res.ParentID,
		GroupId:      &res.TermGroup,
		Count:        pointy.GetPointer(uint32(res.Count)),
		Desc:         &res.Description,
		FilteredDesc: &res.DescriptionFiltered,
		Sort:         pointy.GetPointer(uint32(res.Sort)),
		Status:       pointy.GetPointer(uint32(res.Status)),
		CreatedAt:    pointy.GetPointer(modelx.FormatTime(res.CreatedAt, "")),
		UpdatedAt:    pointy.GetPointer(modelx.FormatTime(res.UpdatedAt, "")),
		DeletedAt:    pointy.GetPointer(modelx.FormatNullDotTime(res.DeletedAt, "")),
		Meta:         meta,
		Media:        media,
	}, nil
}
